Historical The All Mighty Object, Revision 1
The All Mighty Object
Euphoria as a One Data-type Language
Here is a novel way to write programs. Euphoria lets you write entire programs using just one data-type; understanding why this is possible will help you program with atoms and sequences.
A computer is a machine that only works with computer numbers; Euphoria is a language that lets you work with computer numbers. Only one data-type is needed and it is called the object. Any object is either empty, a single number, or a collection of numbers--nothing else is possible.
The object data-type does it all. A variable is a name given to the value of an object in Euphoria. To use a variable you must introduce it:
- declare using object and an identifier
object x
- assign a value to the variable
x = 5
Hint: you can save on typing by:
-- introducing on one line object x = 5 -- introducing several variables at once object x = 3, y = 2
Hint: The double dash, - - , is the Euphoria comment marker; anything following a double dash to the end of the line is ignored by the interpreter.
The value you give an object is anything you can imagine and is written in a style most convenient for you.
object z -- any individual value in choice of format -- these are Euphoria "atom" examples z = 4 -- an integer z = -5 -- a negative integer z = 3.14159 -- a real number z = 1_000_000 -- a million using underscores for spacing z = 1e6 -- a million in scientific notation z = 'a' -- the character 'a' -- any collection of values in choice of format -- these are Euphoria "sequence" examples -- use { } for grouping items in an object z = {} -- empty z = { 1, 2, 3, 4, 5} -- a flat list of numbers z = { {1,2}, {3,4}, {5,6} } -- a 2x3 matrix of numbers z = "Hello Euphoria!" -- a character string z = { "one", "two", "three"} -- put strings inside a sequence z = { {1,"one"}, {2,"two"}, {3,"three"} } -- mix values together z = ` Write anything you want. ` -- free-form raw text
You can do anything with an object in your program. An object variable may be huge (only limited by computer memory) on one line and reduced to an integer on the next line. The Euphoria object is very dynamic: create, delete, extend, alter, reshape, change items, remove items, search, sort, ..., lots and lots of possibilities.
It is possible to write a program of any size using just the single object data-type.
Aside: Mathematical numbers are infinite in size (small or large) and in limitless in accuracy. Objects use computer numbers which are limited in size and accuracy. Calculations with computer numbers can be slightly off or even strangely wrong in special cases. Euphoria follows the same IEEE standards as all modern languages; you have to understand how to use computer numbers regardless of your choice of language. Values in an object are either computer integer or computer float numbers.
Displaying Objects
Euphoria converts all values into numbers that a computer can process; only numbers remain. At any time you can use print to display the numbers contained in an object:
Hint: The question mark, ? , is a Euphoria shortcut for print :
-- both ? and print have the same output ? { 3, 3.333 } --> { 3, 3.33 } print(1, { 3, 3.333 } ) --> { 3, 3.333 }
Using print to output a variety of objects:
-- everything is a number print(1, {1,2,3,4} ) --> {1,2,3,4} print(1, 1_000_000 ) --> 1000000 print(1, 'a') --> 97 print(1, "Hello Euphoria") --> {72,101,108,108,111,32,69,117,112,104,111,114,105,97}
Notice that all of the features that make data entry convenient vanish: spacers in numbers are removed and individual characters become integers. What remains is either a single number or a collection of numbers.
But, all is not lost! If you use puts you can display characters and character strings:
-- characters and character strings output as expected puts(1, 'a') --> a puts(1, 97 ) --> a puts(1, "Hello Euphoria") --> Hello Euphoria puts(1, {72,101,108,108,111,32,69,117,112,104,111,114,105,97} ) --> Hello Euphoria
The traditional ASCII standard defines a number:glyph relationship for what we call plain text characters, digits, and punctuation. The current UTF8 standard retains these relationships. (A glyph is "what you see when something gets printed.")
If a number has a "sensible value" then the puts procedure ( short for put string) will display glyphs instead of a numbers. Numbers that do not have a corresponding glyph will display as noise.
Note: A string is a "sequence of characters." A string object is therefore a flat list of items; we say that a string has a simple one-dimensional shape. You can put strings as items inside a larger object; the object is now multi-dimensional; this object contains text data but is no longer a character string. The puts procedure will only display a character string:
-- puts will display a character string object str = "A string is flat." -- puts will NOT display arbitrary text object txt = { "An object ", "can contain text ", "but that object is ", "no longer a string." }
The output for puts:
puts(1, str) --> A string is flat. puts(1, txt) --> error -- sequence found inside character string
Hint: Using puts to display a complex object (even if it contains text) is common mistake.
Again, all is not lost! The display procedure is used to output complicated objects:
include std/console.e display( txt ) -- { -- "An object ", -- "can contain text ", -- "but that object is ", -- "no longer a string." -- }
The display procedure examines the items inside an object, makes an "educated guess", and displays the object in the most readable form it can. Note: Before using display you have to write include std/console.e because this procedure is read from a library file.
Use pretty_print, another library procedure, to display an object in various ways:
include std/pretty.e pretty_print(1, txt, {1} ) -- { -- {65'A',110'n',32' ',111'o',98'b',106'j',101'e',99'c',116't',32' '}, -- {99'c',97'a',110'n',32' ',99'c',111'o',110'n',116't',97'a',105'i',110'n', -- 32' ',116't',101'e',120'x',116't',32' '}, -- {98'b',117'u',116't',32' ',116't',104'h',97'a',116't',32' ',111'o',98'b', -- 106'j',101'e',99'c',116't',32' ',105'i',115's',32' '}, -- {110'n',111'o',32' ',108'l',111'o',110'n',103'g',101'e',114'r',32' ',97'a', -- 32' ',115's',116't',114'r',105'i',110'n',103'g',46'.'} -- } pretty_print(1, txt, {2} ) -- { -- "An object ", -- "can contain text ", -- "but that object is ", -- "no longer a string." -- }
When doing something fancy, it is assumed that you know what you want. You can specify output exactly with the printf procedure:
printf(1, "%s%s%s%s", txt) --> An object can contain text but that object is no longer a string.
The second argument, "%s%s%s%s", is a format string that determines the appearance of txt when it is output. The codes printf uses are similar to those found in most languages.
Object Programming
There is lots of power and flexibilty in the object data-type. If you are only interested in text data then you can input and output character strings just as easily as with a conventional language. If you are only interested in numbers then an object can be any number or collection of numbers. Any data arrangement you can imagine can be represented by an object.
The computer science defines an object as "a location in memory having a value that is referenced by an identifier." This definition of an object has long been used by compiler designers; to a language designer an "object" is a real and tangible thing that makes computers work. In Euphoria, an identifier is used to access just data that belongs to an object. This is the simple and fast way to use objects.
An "object" in an "object oriented programming" (OOP) language is much more complicated. In an OOP language an object identifier is associated with both data and routines. OOP style languages are larger, more complicated, harder to learn, harder to program, and slower than Euphoria. Simple, fast, and friendly can not be used to describe languages like Python, Java, or Ruby. The art of programming is knowing when to use a truck (like an OOP language) or when to use a sports car (like Euphoria.)
Object, Atom, Integer, Sequence, User-Defined
Using only the object data-type is possible, but practical Euphoria programs are designed around atom and sequence data-types. It is best to view an object and an integer as helper data-types; they are used for special purposes.
The object is the root data-type that makes Euphoria operate. Using an object for everything is overkill; we use object data-types sparingly and even call it one of the "helper" data-types. The atom and sequence are the two branches used for most programming. The integer is a branch of the atom type; it is also used as a "helper" data-type. When inventing a user-defined data-type you can use all four built-in data-types and other user-defined types to create the perfect custom type for your program.
When you narrow down the values a variable can represent then programs become: easier to read and write, faster, and less likely to have bugs.
- If a variable is to be used with only individual numbers then the atom is the best choice.
- If your data is always going be be a collection of values then the sequence data-type is the best choice.
- The integer is a subset of the atom data-type; use an integer for counting and indexing.
- The object data-type has special uses when you can not know in advance if a variable will be used for atom values or sequence values. For example a variable that reads a file normally gets a character string and is thus a sequence, but when the file is empty or end-of-file an atom is returned--the object data-type is the only way to read either a sequence or an atom.
- It is possible to define a user-defined data-type to exactly specify what values are permitted for a variable. These data-types are useful when developing a program since they catch errors.
Real programs are written with atom and sequence data-types and use object and integer as "helper" data-types. Larger programs can use user-defined data-types to advantage.
- diff to current revision, view current revision history, backlinks
- Last modified Jul 16, 2013 by _tom